import {Component, ChangeDetectionStrategy} from "@angular/core";
import {Store} from "@ngrx/store";
import {Observable} from "rxjs";
import {ADD_PERSON, REMOVE_PERSON, ADD_GUEST, REMOVE_GUEST, TOGGLE_ATTENDING} from "./actions";

const id = (function () {
  let start = Math.floor(Math.random() * 5000)
  return () => {
    return start++
  }
})()

const partyModel = () => {
  return state => state
    .map(([people,filter]) => {
      return {
        total: people.length,
        people: people.filter(filter),
        attending: people.filter(person => person.attending).length,
        guests: people.reduce((acc, curr) => acc + curr.guests, 0)
      }
    })
}

const attendees = () => {
  return state => state
    .map(s => s.people)
    .distinctUntilChanged()
}

const percentAttending = () => {
  return state => state
    .let(attendees())
    .map(people => {
      const totalAttending = people.filter(person => person.attending).length
      const total = people.length
      return total > 0 ? (totalAttending / total) * 100 : 0
    })
}

@Component({
  selector: 'ngrx-sample',
  templateUrl: 'ngrx-sample.component.html',
  styleUrls: ['style.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class NgrxSampleComponent {
  // public people$
  // public filter$
  // public attending$
  // public guests$

  public model$
  public percentAttendance$

  constructor(private _store: Store<any>) {
    // this.model$ = Observable.combineLatest(
    //   _store.select('people'),
    //   _store.select('partyFilter'),
    //   (people, filter) => {
    //     return {
    //       total: people.length,
    //       people: people.filter(filter),
    //       attending: people.filter(person => person.attending).length,
    //       guests: people.reduce((acc, curr) => acc + curr.guests, 0)
    //     }
    //   })

    this.model$ = Observable.combineLatest(
      _store.select('people'),
      _store.select('partyFilter')
    ).let(partyModel())

    this.percentAttendance$ = _store.let(percentAttending())
  }

  addPerson(name) {
    this._store.dispatch({type: ADD_PERSON, payload: {id: id(), name}})
  }

  removePerson(id) {
    this._store.dispatch({type: REMOVE_PERSON, payload: id})
  }

  addGuest(id) {
    this._store.dispatch({type: ADD_GUEST, payload: id})
  }

  removeGuest(id) {
    this._store.dispatch({type: REMOVE_GUEST, payload: id})
  }

  toggleAttending(id) {
    this._store.dispatch({type: TOGGLE_ATTENDING, payload: id})
  }

  updateFilter(filter) {
    this._store.dispatch({type: filter})
  }
}
